Skip to content

feat(L10): phase 2 — echo residue as a linear undo-capability#41

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/echo-residue-phase2-linear
Jun 14, 2026
Merged

feat(L10): phase 2 — echo residue as a linear undo-capability#41
hyperpolymath merged 1 commit into
mainfrom
claude/echo-residue-phase2-linear

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What

Phase 2 of the Layer-10 echo-residue work (phase 1 = #34). Makes the
reversal residue a first-class linear value. The checker's residue
stack now carries Linear<Echo<T>> (was a bare Echo<T>): push_echo_residue
wraps the residue in Type::Linear, so the consumed-once discipline is
explicit in the carried type, and the single linear use is discharged by
the matching take_echo_residue pop in a later reverse.

The only non-comment code change is that one-line wrap; the rest is the
Idris proof, tests, spec, and docs.

The design decision (worth a look)

A reversal log is an affine capability consumed linearly:

  • Linear consumption — when you do reverse, you consume one specific
    residue exactly once (reverseLinear's (1 e : Echo f y)). Replaying the
    same log twice is rejected: the residue has already been popped, so the
    second reverse is ReverseWithoutResidue.
  • Affine retention — a reversible block need not be paired with a
    reverse. An undo capability that is never exercised is dropped at the
    body boundary, not flagged. Reversibility is a capability, usually unused.

The opposite — strict "must-reverse" linearity, where an un-reversed residue
is a LinearNotConsumed error — is deliberately rejected: it conflates
having an inverse with applying it, and is poor agent ergonomics. Three
new tests lock the affine drop in so a future change cannot silently tighten
it.

Formal model

proofs/idris2/EchoResidueLinear.idr (%default total, zero believe_me,
idris2 --check clean):

  • reverseLinear consumes (1 e : Echo f y) — Idris2's quantity 1 is
    the "consumed exactly once" proof, mirroring 007's planned Linear<Echo<T>>;
  • reverseLinearCorrect — recovered input maps back to y (intrinsic);
  • ResidueCell (Holding/Spent) — the residue carried as agent state
    between handler invocations;
  • takeForReverse — a later handler consumes the cell linearly (Spent → Nothing);
  • holdingReverses / spentDoesNotReverse — cross-handler reversal succeeds
    iff a residue was retained;
  • cellMode — bridges a cell back to the phase-1 Reversibility mode.

Verified locally

  • idris2 --check EchoResidueLinear.idr → exit 0 (and dependency EchoResidue.idr)
  • cargo test -p oo7-core883 lib tests pass (incl. 3 new L10 phase-2 tests), 0 fail
  • cargo fmt -- --check → 0 diffs
  • cargo clippy -- -D warnings (CI-equivalent, no --all-targets) → exit 0
  • A2ML validator on .machine_readable/6a2/ → 0 errors

Still open (its own rung)

Cross-handler named residues need residue-binding surface syntax
(let undo = reversible {…} … later reverse undo). The formal model
(ResidueCell) is already in place; only the grammar change is missing, and
because the grammar is Harvard-guarded that is kept as a separate, carefully-
scoped rung. Until then cross-handler reversal is conservatively rejected by
per-body isolation (sound, if incomplete).

Docs updated in lockstep

spec/TYPE-SYSTEM-SPEC.adoc §11b.4, spec/OPERATIONAL-SEMANTICS.adoc §11.4
(planned → landed), CHANGELOG.md, docs/echo-residue-integration.adoc
(phase-2 section + design-decision subsection + still-open rung), and 6a2
STATE.a2ml.

Note: repo CI may still be gated by the GitHub Actions billing/spending-limit
rejection documented in the session log (account-owner action). All gates
above were therefore verified locally.

https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We


Generated by Claude Code

@hyperpolymath
hyperpolymath marked this pull request as ready for review June 14, 2026 01:36
Layer 10's reversal residue becomes a first-class linear value. The
checker's residue stack now carries `Linear<Echo<T>>` (was a bare
`Echo<T>`): `push_echo_residue` wraps the residue in `Type::Linear`, so
the consumed-once discipline is explicit in the carried type and the
single linear use is discharged by the matching `take_echo_residue` pop
in a later `reverse`.

Discipline: affine capability, linear consumption. A given reversal log
is consumed at most once — a double `reverse` of one residue is rejected
(the linear use, structural in the stack) — while a `reversible` block
need not be paired with a `reverse` at all (an un-reversed residue is NOT
an error; reversibility is a capability, usually unused). The opposite,
strict must-reverse linearity, is deliberately rejected as semantically
wrong and poor agent ergonomics; three new tests lock the affine drop in
so it cannot be silently tightened.

Formal model: proofs/idris2/EchoResidueLinear.idr (%default total, zero
believe_me, idris2 --check clean) — reverseLinear consumes (1 e : Echo f
y); reverseLinearCorrect (recovered input maps back to y, intrinsic);
ResidueCell Holding/Spent carries the residue as agent state between
handlers; takeForReverse (Spent -> Nothing); holdingReverses /
spentDoesNotReverse; cellMode bridges back to the phase-1 mode.

Still open (own rung): cross-handler NAMED residues need residue-binding
grammar syntax (let undo = reversible {...}; reverse undo); the formal
model (ResidueCell) is in place, only Harvard-guarded surface syntax is
missing.

Tests: 3 new typechecker tests; 883 oo7-core lib tests pass. fmt clean;
clippy (CI-equivalent) -D warnings exit 0. Spec (TYPE-SYSTEM-SPEC §11b.4,
OPERATIONAL-SEMANTICS §11.4), CHANGELOG, docs/echo-residue-integration.adoc
and 6a2 STATE updated in lockstep.

https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We
@hyperpolymath
hyperpolymath force-pushed the claude/echo-residue-phase2-linear branch from 09d8485 to 9d7bbca Compare June 14, 2026 01:36
@hyperpolymath
hyperpolymath merged commit 2d1db20 into main Jun 14, 2026
1 of 23 checks passed
@hyperpolymath
hyperpolymath deleted the claude/echo-residue-phase2-linear branch June 14, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants